package com.fdb.efp.nls.service.impl;

import static  com.fdb.basic.sequence.service.DefaultPatternDescriptor.*;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import com.fdb.efp.nls.service.facade.NlsApplyInfoService;
import com.fdb.efp.nls.service.facade.NlsApplyRelationService;
import com.fdb.efp.nls.service.facade.queue.NlsProcessBizService;
import com.fdb.efp.nls.service.vo.NlsApplyInfoVO;
import com.fdb.efp.nls.service.vo.NlsApplyRelationVO;
import com.fdb.efp.nls.service.vo.queue.NlsProcessBizVO;
import com.fdb.basic.framework.core.constant.CountryConstant;
import com.fdb.basic.framework.core.constant.SDicToExternalConstant;
import com.fdb.basic.framework.core.exception.BizException;
import com.fdb.basic.framework.core.util.ValidationUtils;
import com.fdb.basic.framework.core.util.sdic.SDicToExternal;
import com.fdb.efp.cus.service.facade.CusIndivExtService;
import com.fdb.efp.cus.service.vo.CusIndivExtVO;
import com.fdb.efp.esb.common.constant.ESBClientConstance;
import com.fdb.efp.esb.common.constant.InstitutionEnums;
import com.fdb.efp.esb.common.constant.nls.NlsCrrEnum;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.gdrcu.efp.cus.common.CusBankRelEnum;
import com.gdrcu.efp.cus.common.CusStatusEnum;
import com.gdrcu.efp.cus.common.CusTypeEnum;
import com.fdb.basic.framework.core.util.StringUtil;
import com.fdb.basic.sequence.service.DefaultPatternDescriptor;
import com.fdb.basic.sequence.service.PatternDescriptor;
import com.fdb.basic.sequence.service.facade.PatternedLimitableSeqService;
import com.fdb.efp.nls.common.ConsoleConstant;
import com.fdb.efp.nls.common.IrAdjModeEnum;
import com.fdb.efp.nls.common.RateTypeEnum;
import com.fdb.efp.nls.service.facade.PrdInfoService;
import com.fdb.efp.nls.service.vo.PrdInfoVO;
import com.fdb.efp.nls.common.ContConstant;
import com.fdb.efp.nls.service.facade.CtrLoanContService;
import com.fdb.efp.nls.service.vo.CtrLoanContVO;
import com.fdb.efp.cus.service.facade.CusIndivRelService;
import com.fdb.efp.cus.service.facade.CusIndivService;
import com.fdb.efp.cus.service.vo.CusIndivRelVO;
import com.fdb.efp.cus.service.vo.CusIndivVO;
import com.fdb.efp.esb.common.constant.SDicClientConstant;
import com.fdb.efp.esb.common.util.SDicMappingClient;
import com.fdb.efp.esb.service.bo.req.hj.ReqCusInfoCreBean;
import com.fdb.efp.esb.service.bo.resp.hj.RespCusInfoCreBean;
import com.fdb.efp.esb.service.facade.hj.CustomerInfoCreateService;
import com.fdb.efp.rule.common.enumeration.RefuseType;

/**
 * @description:客户建档节点
 * @date:2019年1月3日 下午7:10:12
 * @author:hengyh
 */
@Service("cusCreateService")
public class CusCreateServiceImpl extends SoltServiceImpl {

	@Autowired
	@Qualifier("cusIndivExtService")
	private CusIndivExtService cusIndivExtService;

	private static final Logger log = LoggerFactory.getLogger(CusCreateServiceImpl.class);
	private static final DateTimeFormatter timeStrFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
	public static final PatternDescriptor PATTERN = 
			DefaultPatternDescriptor.of("CREL" + YEAR_4 + MONTH + DAY + SEQ, 8);;
	@Override
	public void doExecute(NlsProcessBizVO nlsProcessBizVo, NlsApplyInfoVO nlsApplyInfoVO) throws Exception {
		String applySeq = nlsProcessBizVo.getApplySeq();
		try {
			log.info("开始进行客户建档插槽,流水号:" + applySeq);
			Objects.requireNonNull(nlsApplyInfoVO);

			/** 去互金开户， 如果网贷存在该客户信息则不开户 **/
			String cusId = cusIndivService.getCusIdByCertCode(nlsApplyInfoVO.getCertType(), nlsApplyInfoVO.getCertCode());
			// 更新客户信息-客户编号赋值互金客户建档返回的用户号
			// 互金客户建档-用户号
			String usrID = "";
			boolean cusIndivExsit = true;
			try {
				if (cusId == null) {
					log.info("网贷不存在该客户，前往互金建档");
					 ReqCusInfoCreBean reqCusInfoCreBean = new ReqCusInfoCreBean();
					// 客户姓名
					reqCusInfoCreBean.setCustNm(nlsApplyInfoVO.getCusName());
					//  证件类型 
					reqCusInfoCreBean.setCertTp(nlsApplyInfoVO.getCertType());
					//  证件号码 
					reqCusInfoCreBean.setCertNo(nlsApplyInfoVO.getCertCode());
					//  签发机关（默认中国） 
					reqCusInfoCreBean.setIssueOrgNm("中国");
					//  手机号码 
					reqCusInfoCreBean.setMblNo(nlsApplyInfoVO.getMobile());
					// 地址
					reqCusInfoCreBean.setCtcAddr(nlsApplyInfoVO.getCertAddr());
					// 性别
					reqCusInfoCreBean.setUserGnd(StringUtils.isBlank(nlsApplyInfoVO.getCusGender()) ? ValidationUtils.getSexFromIdNumber(nlsApplyInfoVO.getCertCode()).getEnname(): nlsApplyInfoVO.getCusGender());
					// 证件有效期
					reqCusInfoCreBean.setIdenEfftDt(StringUtil.isNullorBank(nlsApplyInfoVO.getIndivIdExpDt()) ? "" : indivIdExpDt(nlsApplyInfoVO.getIndivIdExpDt()));
					// 民族
					reqCusInfoCreBean.setEthnic(nlsApplyInfoVO.getEthnic());
					// 客户英文名称
					reqCusInfoCreBean.setClntEnNm("");
					// 发证机关地区码
					reqCusInfoCreBean.setIssueOrgAddrCd("");
					// 最高学历
					/** 【修改】 @qiuyf 2019/01/28  【原语句】 reqCusInfoCreBean.setHighEdu(nlsApplyInfoVO.getEdu()); */
					reqCusInfoCreBean.setHighEdu(SDicMappingClient.getExternalSysDicVal(SDicClientConstant.SYSID_IFP, SDicClientConstant.DEGREE, nlsApplyInfoVO.getEdu()));
					// 国籍
					reqCusInfoCreBean.setNation(StringUtils.isBlank(nlsApplyInfoVO.getCusNational())? CountryConstant.CHN : nlsApplyInfoVO.getCusNational());
					// 职业
					try {
						reqCusInfoCreBean.setCrrCd(StringUtils.isBlank(nlsApplyInfoVO.getProfession()) ? NlsCrrEnum.UNKNOWN.getValue() : (SDicToExternal.getExternalSysDicVal(SDicToExternalConstant.SYSID_IFP, SDicToExternalConstant.CRR, nlsApplyInfoVO.getProfession())));
					} catch (Exception e) {
						e.printStackTrace();
						log.error("本地系统字典项转互金接口所需字典项出错，请核查配置文件(dicExternal.properties)！");
					}
					// 职称
					reqCusInfoCreBean.setTtl(nlsApplyInfoVO.getTtl());
					// 出生日期
					reqCusInfoCreBean.setBrthDt(nlsApplyInfoVO.getBrthDt());
					// 工作单位名称
					reqCusInfoCreBean.setWrkCorpNm(nlsApplyInfoVO.getWrkCorpNm());
					// 工作单位地址
					reqCusInfoCreBean.setWrkCorpAddr(nlsApplyInfoVO.getWrkCorpAddr());
					// 工作单位电话
					reqCusInfoCreBean.setWrkCorpTel(nlsApplyInfoVO.getWrkCorpTel());
					// 家庭地址
					reqCusInfoCreBean.setFamAddr(nlsApplyInfoVO.getFamAddr());
					// 家庭电话
					reqCusInfoCreBean.setFamTelNo(nlsApplyInfoVO.getFamTelNo());
					// 个人月收入
					reqCusInfoCreBean.setIndvIncmAmt("");
					// 家庭月收入
					reqCusInfoCreBean.setFamIncmAmt("");
					// 婚姻状况
					reqCusInfoCreBean.setMrgSitu(nlsApplyInfoVO.getMrgSitu());
					// 配偶姓名
					reqCusInfoCreBean.setSpsNm(nlsApplyInfoVO.getSpsNm());
					// 配偶联系电话
					reqCusInfoCreBean.setSpsCtcTelNo(nlsApplyInfoVO.getSpsCtcTelNo());
					// 配偶移动电话
					reqCusInfoCreBean.setSpsMblTelNo(nlsApplyInfoVO.getSpsMblTelNo());
					// 配偶客户号
					reqCusInfoCreBean.setSpsCustNo("");
					// 邮编
					reqCusInfoCreBean.setPstcd(nlsApplyInfoVO.getPstcd());
					// 单位性质
					reqCusInfoCreBean.setCorpChar(nlsApplyInfoVO.getCorpChar());
					// 是否农户 转换字典项
					String whthrFrmr = SDicToExternal.getExternalSysDicVal(SDicToExternalConstant.SYSID_IFP,SDicToExternalConstant.WhthrFrmr,nlsApplyInfoVO.getWhthrFrmr() );
					reqCusInfoCreBean.setWhthrFrmr(whthrFrmr);
					reqCusInfoCreBean.setInstId(ESBClientConstance.msInstId);
					// 产品类型  【需求变更】 @date 2019/06/27
					reqCusInfoCreBean.setProdType(SDicToExternal.getExternalSysDicVal(SDicToExternalConstant.SYSID_IFP, SDicToExternalConstant.PRD_TYPE, nlsApplyInfoVO.getPrdId()));
					RespCusInfoCreBean respCusInfoCreBean = customerInfoCreateService.customerInfoCreate(reqCusInfoCreBean);
					cusId = respCusInfoCreBean.getClntNo();
					// 互金客户建档-用户号
					usrID = respCusInfoCreBean.getUsrID();
					cusIndivExsit = false;
				} else {
					log.info("网贷已存在该客户，客户号：" + cusId);
				}
			} catch (Exception e) {
				log.error("调用互金核心客户建档异常", e);
				nlsProcessBizVo.setRefuseMsg(RefuseType.OTHER.getMsg());
				throw new BizException("调用互金核心客户建档异常", e);
			}
			String prdId = Objects.requireNonNull(nlsApplyInfoVO.getPrdId());
			PrdInfoVO prdInfoVo = new PrdInfoVO();
			prdInfoVo.setPrdId(prdId);
			prdInfoVo = prdInfoService.queryByPk(prdInfoVo);

			final String dateString = LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE);
			final String dateTimeString = LocalDateTime.now().format(timeStrFormatter);
			final String createUser = "admin";

			/** 新增客户信息(如果不存在该客户信息) **/
			final CusIndivVO cusIndivVO = new CusIndivVO();
			cusIndivVO.setCusId(cusId);
			cusIndivVO.setInnerCusId(cusId);
			cusIndivVO.setCusName(nlsApplyInfoVO.getCusName());
			/** 客户性别按照报文落表，不做逻辑校验 2020.08.21 wengqingw**/
			cusIndivVO.setIndivSex(nlsApplyInfoVO.getCusGender());
			cusIndivVO.setIndivIdExpDt(nlsApplyInfoVO.getIndivIdExpDt());
			cusIndivVO.setCertType(nlsApplyInfoVO.getCertType());
			cusIndivVO.setCertCode(nlsApplyInfoVO.getCertCode());
			cusIndivVO.setPhone(nlsApplyInfoVO.getMobile());
			cusIndivVO.setCusType(CusTypeEnum.NATURAL_MAN.getCode());
			cusIndivVO.setCusBankRel(CusBankRelEnum.NORMAL.getCode());
			cusIndivVO.setIndivHouhRegAdd(nlsApplyInfoVO.getCertAddr());
			cusIndivVO.setCusStatus(CusStatusEnum.OFFICIAL.getCode());
			cusIndivVO.setIndivCountry(nlsApplyInfoVO.getCusNational());
			// 民族
			cusIndivVO.setIndivNtn(nlsApplyInfoVO.getEthnic());
			// 是否农户
			cusIndivVO.setAgriFlg(nlsApplyInfoVO.getWhthrFrmr());
			// 学历
			cusIndivVO.setIndivEdt(nlsApplyInfoVO.getEdu());
			// 工作单位名称
			cusIndivVO.setIndivComName(nlsApplyInfoVO.getWrkCorpNm());
			// 工作单位地址
			cusIndivVO.setIndivComAddr(nlsApplyInfoVO.getWrkCorpAddr());
			// 配偶姓名
			cusIndivVO.setIndivSpsName(nlsApplyInfoVO.getSpsNm());
			// 职称
			cusIndivVO.setIndivCrtfctn(nlsApplyInfoVO.getTtl());
			// 邮编
			cusIndivVO.setPostCode(nlsApplyInfoVO.getPstcd());
			// 个人月收入
			cusIndivVO.setIndivAnnIncm(nlsApplyInfoVO.getIndvIncmAmt());
			// 家庭月收入
			cusIndivVO.setFamilyMincm(nlsApplyInfoVO.getFamIncmAmt());
			// 居住地址
			cusIndivVO.setIndivRsdAddr(nlsApplyInfoVO.getIndivRsdAddr());
			// 户籍地址
			cusIndivVO.setIndivHouhRegAdd(nlsApplyInfoVO.getCertAddr());
			// 家庭地址
			cusIndivVO.setFamilyAddr(nlsApplyInfoVO.getFamAddr());
			// 首次申请渠道
			cusIndivVO.setFstAppChannel(prdInfoVo.getPrdType());
			// 婚姻状况
			cusIndivVO.setIndivMarSt(nlsApplyInfoVO.getMrgSitu());
			// 配偶移动电话
			cusIndivVO.setIndivSpsMphn(nlsApplyInfoVO.getSpsMblTelNo());
			// 配偶联系电话
			cusIndivVO.setIndivSpsPhone(nlsApplyInfoVO.getSpsCtcTelNo());
			// 家庭电话
			cusIndivVO.setFphone(nlsApplyInfoVO.getFamTelNo());
			// 通讯地址
			cusIndivVO.setPostAddr(nlsApplyInfoVO.getAplCmmAddr());
			// 职业
			cusIndivVO.setIndivOcc(nlsApplyInfoVO.getProfession());
			// 单位性质
			cusIndivVO.setIndivComTyp(nlsApplyInfoVO.getCorpChar());
			// 出生年月日
			cusIndivVO.setIndivDtOfBirth(nlsApplyInfoVO.getBrthDt());

			cusIndivVO.setInputId(createUser);
			cusIndivVO.setLastUpdateTime(dateTimeString);
			cusIndivVO.setLastUpdateUser(createUser);

			// 更新客户信息-客户编号赋值互金客户建档返回的用户号
			if(!StringUtil.isNullorBank(usrID)){
				cusIndivVO.setCusId(usrID);
				cusId = cusIndivVO.getCusId();
			}
			
			if (cusIndivExsit) {
				int num1 = cusIndivService.updateByPk(cusIndivVO);
				if (num1 == -1) {
					throw new BizException("客户数据表更新异常!");
				}
			} else {
				cusIndivVO.setComInitLoanDate(dateString);
				cusIndivVO.setInputDate(dateString);
				cusIndivVO.setCreateTime(dateTimeString);
				int num2 = cusIndivService.insertCusIndiv(cusIndivVO);

				//客户信息扩展表，用于联网核查
				CusIndivExtVO cusIndivExtVO=new CusIndivExtVO();
				cusIndivExtVO.setCusId(usrID);
				cusIndivExtVO.setOnlineVerfStatus("0");//联网核查状态 0 未核查，
				cusIndivExtVO.setCreateUser(createUser);
				cusIndivExtVO.setCreateTime(dateTimeString);
				cusIndivExtVO.setLastUpdateUser(createUser);
				cusIndivExtVO.setLastUpdateTime(dateTimeString);
				int num3=cusIndivExtService.insert(cusIndivExtVO);

				if (num2 == -1 || num3==-1) {
					throw new BizException("客户数据表增加异常!");
				}
			}
			
			/** 插入贷款合同表 **/
			final CtrLoanContVO ctrLoanContVO = new CtrLoanContVO();
			ctrLoanContVO.setContNo(applySeq);
			ctrLoanContVO.setSerno(applySeq);
			ctrLoanContVO.setContType(ConsoleConstant.CONT_TYPE_02); // 合同类型 -- 借款合同
			ctrLoanContVO.setPrdCode(prdInfoVo.getPrdCode());
			ctrLoanContVO.setPrdId(prdInfoVo.getPrdId());
			ctrLoanContVO.setPrdName(prdInfoVo.getPrdName());
			ctrLoanContVO.setCusId(cusId);
			ctrLoanContVO.setCusName(nlsApplyInfoVO.getCusName());
			ctrLoanContVO.setCertCode(nlsApplyInfoVO.getCertCode());
			ctrLoanContVO.setCertType(nlsApplyInfoVO.getCertType());
			ctrLoanContVO.setTermTimeType(nlsApplyInfoVO.getLoanTermType()); // 期限类型
			ctrLoanContVO.setLoanTerm(new BigDecimal(nlsApplyInfoVO.getLoanTerm()));
			ctrLoanContVO.setApprovalAmt(nlsApplyInfoVO.getApplyAmt()); // 审批金额
			ctrLoanContVO.setContAmt(nlsApplyInfoVO.getApplyAmt()); // 合同金额
			ctrLoanContVO.setAvailAmt(BigDecimal.ZERO); // 合同可用金额
			ctrLoanContVO.setTotalIssueAmt(nlsApplyInfoVO.getApplyAmt()); // 累计发放金额
			ctrLoanContVO.setContState(ContConstant.CONT_STATUS_101); // 合同状态 - 待签订
			ctrLoanContVO.setContStartDt(nlsApplyInfoVO.getApplyDate()); // 起始日
			ctrLoanContVO.setContEndDt(LocalDate.parse(nlsApplyInfoVO.getApplyDate())
					.plusMonths(Long.valueOf(nlsApplyInfoVO.getLoanTerm()))
					.format(DateTimeFormatter.ISO_LOCAL_DATE));
			ctrLoanContVO.setIntRateType(RateTypeEnum.NORMAL.getCode()); // 普通贷款
			ctrLoanContVO.setIrAdjustMode(IrAdjModeEnum.FIXED.getCode()); // 固定利率
			ctrLoanContVO.setUseDec(nlsApplyInfoVO.getLoanPurpose()); // 借款用途
			ctrLoanContVO.setChannelCode(nlsApplyInfoVO.getChannelNo());
			ctrLoanContVO.setCreateUser(createUser);
			ctrLoanContVO.setCreateTime(dateTimeString);
			ctrLoanContVO.setLastUpdateTime(dateTimeString);
			ctrLoanContVO.setLastUpdateUser(createUser);
			// add by ludayong 2019/11/15 【数据权限】增加登记机构赋值
			// 登记机构
			ctrLoanContVO.setInputBrId(InstitutionEnums.InstitutionEnum.GZYHZHYHZXSCTD2.getCode());
			ctrLoanContService.insertCtrLoanCont(ctrLoanContVO);
			
			/** 更新进件申请表 **/
			if (!Objects.equals(nlsApplyInfoVO.getCusId(), cusId)) {
				nlsApplyInfoVO.setCusId(cusId);
				nlsApplyInfoService.updateByPk(nlsApplyInfoVO);
			}
			
			/** 插入客户关系人表 **/
			//查询客户进件联系人
			final NlsApplyRelationVO nlsApplyRelationVo = new NlsApplyRelationVO();
			nlsApplyRelationVo.setApplySeq(applySeq);
			List<NlsApplyRelationVO> nlsApplyRelationVOs = Optional.ofNullable(nlsApplyRelationService.queryByApplySeq(nlsApplyRelationVo)).orElseGet(ArrayList::new);
			//查询当前客户存量客户联系人
			final CusIndivRelVO cusIndivRelVO = new CusIndivRelVO();
			cusIndivRelVO.setCusId(ctrLoanContVO.getCusId());
			List<CusIndivRelVO> cusIndivRelVOs = Optional.ofNullable(cusIndivRelService.queryByPkCusId(cusIndivRelVO)).orElseGet(ArrayList::new);
			
			CusIndivRelVO cusIndivRelVoNew = new CusIndivRelVO();
			for (NlsApplyRelationVO vo : nlsApplyRelationVOs) {
				String relSerno = "";
				cusIndivRelVoNew.setRelSerno(relSerno);
				cusIndivRelVoNew.setCusId(ctrLoanContVO.getCusId());
				cusIndivRelVoNew.setCertCode(vo.getCertCode());
				cusIndivRelVoNew.setCertType(vo.getCertType());
				cusIndivRelVoNew.setRelName(vo.getRelName());
				cusIndivRelVoNew.setRelation(vo.getRelRelation());
				cusIndivRelVoNew.setMobile(nlsApplyInfoVO.getMobile());
				cusIndivRelVoNew.setLastUpdateTime(dateTimeString);
				//如果存在存量联系人，则循环对比，不存在联系人则直接插入
				if(cusIndivRelVOs.size()>0) {
					for(CusIndivRelVO cus : cusIndivRelVOs) {
						if(vo.getCusName().equals(cus.getRelName())) {//姓名相同则更新,姓名不同则插入
							cusIndivRelService.updateByPk(cusIndivRelVoNew);
						}else {
							try {
								relSerno = sequenceService.getPatternedSequence("CUS_REL_SERNO", PATTERN);
							} catch (Exception e) {
								throw new BizException("关系人流水号生成失败");
							}
							cusIndivRelVoNew.setRelSerno(relSerno);
							cusIndivRelVoNew.setCreateTime(dateTimeString);
							cusIndivRelService.insertCusIndivRel(cusIndivRelVoNew);
						}
					}
				}else {
					try {
						relSerno = sequenceService.getPatternedSequence("CUS_REL_SERNO", PATTERN);
					} catch (Exception e) {
						throw new BizException("关系人流水号生成失败");
					}
					cusIndivRelVoNew.setRelSerno(relSerno);
					cusIndivRelVoNew.setCreateTime(dateTimeString);
					cusIndivRelVoNew.setLastUpdateTime(dateTimeString);
					cusIndivRelService.insertCusIndivRel(cusIndivRelVoNew);
				}
			}
		} catch (Exception e) {
			log.error(Arrays.toString(e.getStackTrace()));
			nlsProcessBizVo.setExceptionFlag(true);
			nlsProcessBizVo.setExceptionMsg(e);
		}
	}
	
	/**
	 * 证件有效期截取
	 * @param indivIdExpDt
	 */
	public String indivIdExpDt(String indivIdExpDt) {
		String[] indiv = indivIdExpDt.split("-");
		if("长期".equals(indiv[1])) {
			return "20991231";
		}
		return indiv[1];
	}
	

	@Autowired
	@Qualifier("nlsApplyInfoService")
	private NlsApplyInfoService nlsApplyInfoService;
	@Autowired
	@Qualifier("nlsApplyRelationService")
	private NlsApplyRelationService nlsApplyRelationService;
	@Autowired
	@Qualifier("customerInfoCreateService")
	private CustomerInfoCreateService customerInfoCreateService;
	@Autowired
	private PatternedLimitableSeqService sequenceService;
	@Autowired
	@Qualifier("prdInfoService")
	private PrdInfoService prdInfoService;
	@Autowired
	@Qualifier("ctrLoanContService")
	private CtrLoanContService ctrLoanContService;
	@Autowired
	@Qualifier("cusIndivService")
	private CusIndivService cusIndivService;
	@Autowired
	@Qualifier("cusIndivRelService")
	private CusIndivRelService cusIndivRelService;
	@Autowired
	@Qualifier("nlsProcessBizService")
	private NlsProcessBizService nlsProcessBizService;

}
